/*
 Copyright (C) 2010 Kristian Duske

 This file is part of TrenchBroom.

 TrenchBroom is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 TrenchBroom is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "Result.h"
#include "mdl/EntityDefinitionFileSpec.h"
#include "mdl/GameFileSystem.h"
#include "mdl/SoftMapBounds.h"

#include <filesystem>
#include <string>
#include <vector>

namespace tb
{
class Logger;

namespace mdl
{
class Entity;
class EntityNodeBase;

struct EntityPropertyConfig;
struct GameInfo;

class Game
{
private:
  const GameInfo& m_gameInfo;
  GameFileSystem m_fs;

public:
  Game(const GameInfo& gameInfo, Logger& logger);

public:
  const GameInfo& info() const;
  const GameConfig& config() const;
  const fs::FileSystem& gameFileSystem() const;

  void updateFileSystem(
    const std::vector<std::filesystem::path>& searchPaths, Logger& logger);

  SoftMapBounds extractSoftMapBounds(const Entity& entity) const;

  void reloadWads(
    const std::filesystem::path& documentPath,
    const std::vector<std::filesystem::path>& wadPaths,
    Logger& logger);

  bool isEntityDefinitionFile(const std::filesystem::path& path) const;
  std::vector<EntityDefinitionFileSpec> allEntityDefinitionFiles() const;
  std::filesystem::path findEntityDefinitionFile(
    const EntityDefinitionFileSpec& spec,
    const std::vector<std::filesystem::path>& searchPaths) const;

  Result<std::vector<std::string>> availableMods() const;
  std::string defaultMod() const;

private:
  void initializeFileSystem(
    const std::vector<std::filesystem::path>& searchPaths, Logger& logger);

  EntityPropertyConfig entityPropertyConfig() const;

  void writeLongAttribute(
    EntityNodeBase& node,
    const std::string& baseName,
    const std::string& value,
    size_t maxLength) const;
  std::string readLongAttribute(
    const EntityNodeBase& node, const std::string& baseName) const;
};

} // namespace mdl
} // namespace tb
